#ifndef __S_EDGE_NURBS__
#define __S_EDGE_NURBS__

#include "element.h"

class Node;
class STriangle;

class SEdge : public ElementImplementation<SEdge> {
public:
	SEdge(Attribute& attribute, size_t id);
	void Init(Node* a, Node* b, STriangle* triangle, SEdge* neighbor = 0);

	SEdge(Node* v0, Node* v1, Attribute& attribute, size_t id);

	virtual const Node* GetNode(size_t i) const {
		if(i == 0) return a;
		if(i == 1) return b;
	}

	template<typename T> void EvaluateImplementation(T& x, const Vector& P, size_t attributeHandle) const;
	template<typename T> void IntegrateImplementation(T& x, const Node* node, size_t attributeHandle) const;

	/////////////////////

	Node* a;
	Node* b;
	STriangle* triangle;

	SEdge* neighbor;

	Vec3n Center(const std::string& attribute = "position") const;
	Vec3n Direction(const std::string& attribute = "position") const;
	Vec3n Normal(const std::string& attribute = "position") const;
	nfloat Parameter(const Vec3n& P, size_t target) const;
	nfloat Length(const std::string& attribute = "position") const {return math::length(a->Get<Vec3n>(attribute) - b->Get<Vec3n>(attribute));}

	size_t& Mark() {return Get<size_t>("mark");}
	const size_t& Mark() const {return Get<size_t>("mark");}
private:

};

template<typename T>
void SEdge::EvaluateImplementation(T& x, const Vector& P, size_t attributeHandle) const {
	assert(P.size() == 1);
	const nfloat& u = P(0);
	x = u * a->Get<T>(attributeHandle) + (1.0 - u) * b->Get<T>(attributeHandle);
}

template<typename T>
void SEdge::IntegrateImplementation(T& x, const Node* node, size_t attributeHandle) const {
	std::cout << "IMPLEMENT SEDGE INTERGRATION!" << std::endl;
}

SEdge* AdjacentEdge(STriangle* t1, STriangle* t2);

#endif //__S_EDGE_NURBS__

